1 module d_tree_sitter.language;
2 
3 extern (C):
4 
5 import std.exception : enforce;
6 import std..string : fromStringz, toStringz;
7 
8 /**
9   An opaque object that defines how to parse a particular language. The code for each
10   `Language` is gen by the Tree-sitter CLI.
11 */
12 struct Language
13 {
14   import d_tree_sitter.libc : TSLanguage, ts_language_version,
15     ts_language_symbol_count, ts_language_symbol_name, ts_language_symbol_for_name,
16     ts_language_symbol_type, TSSymbolType, ts_language_field_count,
17     ts_language_field_name_for_id, ts_language_field_id_for_name;
18 
19   /** internal TSLanguage */
20   const TSLanguage* tslanguage;
21 
22   /** create a new Language. */
23   this(const TSLanguage* tslanguage) @nogc nothrow
24   {
25     assert(tslanguage != null, "The given tslanguage is null");
26     this.tslanguage = tslanguage;
27   }
28 
29   /**
30    Get the ABI version number that indicates which version of the Tree-sitter CLI
31    that was used to generate this `Language`.
32   */
33   auto get_version() @nogc nothrow
34   {
35     return ts_language_version(tslanguage);
36   }
37 
38   /** Get the number of distinct node types in language. */
39   auto node_kind_count() @nogc nothrow
40   {
41     return ts_language_symbol_count(tslanguage);
42   }
43 
44   /** Get the name of the node kind for the given numerical id. */
45   auto node_kind_for_id(ushort id) @nogc nothrow
46   {
47     auto ptr = ts_language_symbol_name(tslanguage, id);
48     return fromStringz(ptr);
49   }
50 
51   /** Get the numeric id for the given node kind. */
52   auto id_for_node_kind(string kind, bool named)
53   {
54     auto kind_len = cast(uint) kind.length;
55     auto kind_c = toStringz(kind);
56     return ts_language_symbol_for_name(tslanguage, kind_c, kind_len, named);
57   }
58 
59   /**
60     Check if the node type for the given numerical id is named (as opposed
61     to an anonymous node type).
62   */
63   auto node_kind_is_named(ushort id) @nogc nothrow
64   {
65     return ts_language_symbol_type(tslanguage, id) == TSSymbolType.TSSymbolTypeRegular;
66   }
67 
68   /**
69     Check if the node type for the given numerical id is anonymous (as opposed
70     to a named node type).
71   */
72   auto node_kind_is_visible(ushort id) @nogc nothrow
73   {
74     return ts_language_symbol_type(tslanguage, id) <= TSSymbolType.TSSymbolTypeAnonymous;
75   }
76 
77   /** Get the number of distinct field names in this language. */
78   auto field_count() @nogc nothrow
79   {
80     return ts_language_field_count(tslanguage);
81   }
82 
83   /** Get the field names for the given numerical id. */
84   auto field_name_for_id(ushort field_id) @nogc nothrow
85   {
86     auto ptr = ts_language_field_name_for_id(tslanguage, field_id);
87     return fromStringz(ptr);
88   }
89 
90   /** Get the numerical id for the given field name. */
91   auto field_id_for_name(string field_name)
92   {
93     auto field_name_len = cast(uint) field_name.length;
94     auto field_name_c = toStringz(field_name);
95     auto id = ts_language_field_id_for_name(tslanguage, field_name_c, field_name_len,);
96     enforce(id != 0, "numerical id for the given field name is 0.");
97     return id;
98   }
99 }